package org.fhnw.aigs.Minesweeper.client; import javafx.application.Platform; import org.fhnw.aigs.Minesweeper.commons.MinesweeperField; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Pane; /** * The graphical representation of a Minesweeper field * @author Matthias Stöckli (v1.0) * @version 1.1 (Raphael Stoeckli) */ public class MinesweeperPane extends Pane { /** * Provides a graphic. It can be a mine count number, a mine or a flag. */ private ImageView imageView; /** * The field height. */ private double height; /** * The field width. */ private double width; /** * Creates a new instance of MinesweeperPane and styles it. */ public MinesweeperPane() { super(); this.width = getWidth(); this.height = getHeight(); this.imageView = new ImageView(); this.getStyleClass().add("minesweeperField"); this.getChildren().add(imageView); } /** * Sets a flag (marks mine). */ public void setFlag() { this.width = getWidth(); this.height = getHeight(); //imageView.setImage(new Image("/Assets/Images/flag.png", height, width, true, false)); setImage(imageView, new Image("/Assets/Images/flag.png", height, width, true, false)); } /** * Remove the image, e.g. the flag. */ public void removeImage() { //imageView.setImage(null); setImage(imageView, null); } /** * Changes the style of the field so that it appears to be covered again. * This will be used if you restart the game. */ void cover() { //this.getStyleClass().clear(); //this.getStyleClass().add("minesweeperField"); clearStyle(this); // Invoke addStyle(this, "minesweeperField"); // Invoke } /** * Uncover the field. This changes the style of the image and shows the number * of surrounding mines or the mine if there is one. * @param field The logical reprsentation of that field. */ public void uncover(MinesweeperField field) { this.width = getWidth(); this.height = getHeight(); addStyle(this, "empty"); // Invoke if(field.getHasFlag()){ removeImage(); } if (field.getSurroundingMinesCount() > 0) { setImage(imageView, new Image("/Assets/Images/" + field.getSurroundingMinesCount() + ".png", height, width, true, false)); // Invoke } if (field.getContainsMine()){ removeImage(); addStyle(this, "mineRed"); // Invoke } } /** * Adds a new style in JavaFX by invoking.<br>This method is needed because the program will crash if an existing part of a window element is changed without invoking. * @param pane the reference to the pane. Most time 'this' * @param styleName The new style name * @since Version 1.1 (Raphael Stoeckli) */ public void addStyle(MinesweeperPane pane, String styleName) { // IMPORTANT - Invoking! // This code is needed by JavaFX. If a style is changed outside of Platform.runLater, the programm will crash! Platform.runLater(new Runnable(){ @Override public void run() { pane.getStyleClass().add(styleName); } }); } /** * Removes all styles in JavaFX by invoking.<br>This method is needed because the program will crash if an existing part of a window element is changed without invoking. * @param pane the reference to the pane. Most time 'this' * @since Version 1.1 (Raphael Stoeckli) */ public void clearStyle(MinesweeperPane pane) { // IMPORTANT - Invoking! // This code is needed by JavaFX. If a style is changed outside of Platform.runLater, the programm will crash! Platform.runLater(new Runnable(){ @Override public void run() { pane.getStyleClass().clear(); } }); } /** * Draws the new image in JavaFX by invoking.<br>This method is needed because the program will crash if an existing part of a window element is changed without invoking. * @param imageView The ImageView object (field on board) to change * @param image The new image object * @since Version 1.1 (Raphael Stoeckli) */ public void setImage(ImageView imageView, Image image) { // IMPORTANT - Invoking! // This code is needed by JavaFX. If an image is changed outside of Platform.runLater, the programm will crash! Platform.runLater(new Runnable(){ @Override public void run() { imageView.setImage(image); } }); } }